fix(arrs): skip queue items from other download clients#525
Merged
Conversation
Adds a generic import_migrations table to track two-phase migration state (Phase 1 = import NZBs into AltMount; Phase 2 = rewrite arr library symlinks). Includes goose migrations for SQLite and PostgreSQL, ImportMigration model + status consts, a full ImportMigrationRepository with Upsert/MarkImported/MarkFailed/MarkSymlinksMigrated/LookupByExternalID/ ListByStatus/Stats/ExistsForSource/BackfillFromImportQueue, and wires MigrationRepo into the DB struct.
…avIds Delete HandleIDMetadataLinks and id_linker.go; remove UpdateIDSymlink and RemoveIDSymlink methods from MetadataService; remove the .id sidecar write block from WriteFileMetadata (read path preserved for Phase 2 compatibility); remove FilterExistingNzbdavIds from QueueRepository, Repository, and the BatchQueueAdder interface; remove related call sites in nzbfilesystem MOVE handler and nzbdav scanner processBatch.
- Add MigrationRecorder interface to scanner package with UpsertMigration and IsMigrationCompleted methods - Update NzbDavImporter to accept MigrationRecorder as second constructor parameter alongside BatchQueueAdder - processBatch now checks IsMigrationCompleted before enqueueing (skip already-imported/symlinks_migrated items) and calls UpsertMigration for new items, then strips nzbdav_id from the queue item metadata leaving only extracted_files if present - createNzbFileAndPrepareItem sets SkipArrNotification=true on all items - batchQueueAdapterForImporter gains migrationRepo field and implements MigrationRecorder via ImportMigrationRepository.Upsert/LookupByExternalID
…lure Wire s.database.MigrationRepo into handleProcessingSuccess and handleProcessingFailure so that import_migrations rows are marked imported/failed when the corresponding queue item finishes. Both calls are non-fatal: failures are logged as warnings and do not affect the main processing outcome. If no matching migration row exists (non-nzbdav import), the UPDATE simply affects 0 rows.
Adds RewriteLibrarySymlinks in internal/importer/migration to walk a library directory and atomically rewrite arr symlinks that point at <nzbdav_mount>/.ids/<guid> to the final altmount path. Introduces DBSymlinkLookup adapter in internal/database, a new POST /import/nzbdav/migrate-symlinks handler, and enriches the existing status endpoint with migration_stats when available.
The ARR queue cleanup worker iterated every queue record and, via the path-gone ghost check, removed items whose OutputPath was invisible to AltMount — which includes items owned by other download clients (qBittorrent, real SABnzbd, etc.). Filter the cleanup loops by DownloadClient so only AltMount's own items are ever touched. Fixes #523
…se-fa18e1 # Conflicts: # internal/api/nzbdav_handlers.go # internal/api/server.go # internal/database/import_migration_repository.go # internal/database/symlink_lookup.go # internal/importer/migration/symlinks.go # internal/importer/migration/symlinks_test.go # internal/importer/scanner/nzbdav.go # internal/importer/service.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #523 — the ARR queue cleanup worker was removing queue items belonging to other download clients (qBittorrent, real SABnzbd, NZBGet…), not just AltMount's own.
Root cause:
cleanupRadarrQueue/cleanupSonarrQueueininternal/arrs/worker/worker.goiterated every record returned by the ARR queue API. TheisGhostByPathGonecheck thenos.Stat'd theOutputPath; for items owned by other clients the path often points to a volume AltMount cannot see, soStatfails, the 60s observation window elapses, and the item is deleted from the ARR queue withremoveFromClient=true. Symptom in logs:Fix: Skip any queue record whose
DownloadClientfield does not match AltMount's registered client name. The cleanup worker exists to clean up AltMount's own imports — touching other clients' items is never intentional.Changes
internal/arrs/registrar/manager.go— exportAltmountDownloadClientName = "AltMount (SABnzbd)"as a package constant and use it fromEnsureDownloadClientRegistration, so both registrar and worker share one source of truth.internal/arrs/worker/worker.go— importregistrar; at the top of the queue loop in bothcleanupRadarrQueueandcleanupSonarrQueue,continuewhenq.DownloadClient != registrar.AltmountDownloadClientName.The webhook handler (
internal/api/arrs_handlers.go) was not changed — it only reacts to import/rename/delete events for the single file in the payload and cannot mass-remove other clients' items.Test plan
go build ./internal/arrs/...go vet ./internal/arrs/...go test -race ./internal/arrs/...— all greenFound ghost queue itemlog for that item).